package cn.xzqwjw.taskmanager.domain.pojo;

import cn.xzqwjw.taskmanager.common.validator.EmailValidator;
import cn.xzqwjw.taskmanager.common.validator.ValidGroupAdd;
import cn.xzqwjw.taskmanager.common.validator.ValidGroupUpdate;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author rush
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class SysAdmin extends Model<SysAdmin> implements UserDetails, Serializable {

  @TableField(exist = false)
  private static final long serialVersionUID = 1L;

  @Override
  public Serializable pkVal() {
    return this.id;
  }

  /**
   * 只在分组为 ValidGroupUpdate（更新时id不能为空）的情况下进行验证
   */
  @TableId(value = "id", type = IdType.AUTO)
  @NotNull(message = "id不能为空", groups = ValidGroupUpdate.class)
  private Integer id;

  /**
   * uuid是36位的，其中包含32个字符以及4个'-'分隔符
   */
  @NotBlank(message = "uuid不能为空！", groups = ValidGroupUpdate.class)
  @Length(min = 32, max = 32, message = "uuid长度应为{max}")
  private String uuid;

  /**
   * 管理员idOpen
   */
  private Long idOpen;

  /**
   * 所属单位id
   */
  private Integer idUnit;

  /**
   * 所属科室id
   */
  private Integer idDepartment;

  /**
   * 管理员登录名
   * 如果不分配groups，则默认每次都要进行验证
   */
  @NotBlank(message = "管理员登录名不能为空！")
  @Length(min = 4, max = 20, message = "姓名长度应为{min}到{max}")
  private String username;

  /**
   * 密码，凡是被 transient 修饰符修饰的字段不会被序列化
   */
  @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
  @NotBlank(message = "密码不能为空！", groups = ValidGroupAdd.class)
  @Length(min = 6, max = 128, message = "密码长度应为{min}到{max}")
  private String password;

  /**
   * 真实姓名
   */
  @Length(max = 20, message = "长度不能超过{max}个字符")
  private String realName;

  /**
   * 笔名
   */
  @Length(max = 50, message = "长度不能超过{max}个字符")
  private String penName;

  /**
   * 性别
   */
  @Length(max = 10, message = "长度不能超过{max}个字符")
  private String gender;

  /**
   * 身份证号码
   */
  @Length(max = 18, message = "身份证号码长度不能超过{max}个字符")
  private String idCard;

  /**
   * 手机号码
   */
  @Length(max = 20, message = "手机号码长度不能超过{max}个字符")
  private String mobilePhone;

  /**
   * 联系邮箱地址
   */
  // @Pattern(regexp = "^(.+)@(.+)$", message = "邮箱的格式不合法")
  @EmailValidator
  @Length(max = 100, message = "长度不能超过{max}个字符")
  private String email;

  /**
   * 头像图片地址
   */
  @Length(max = 1000, message = "长度不能超过{max}个字符")
  private String avatarUrl;

  /**
   * 添加该管理员的管理员id
   */
  private Integer createAdminId;

  /**
   * 最后一次登录时间
   */
  private LocalDateTime dtLastLogin;

  /**
   * 管理员添加时间
   */
  private LocalDateTime dtCreate;

  /**
   * 账号是否可用
   */
  private boolean isEnabled;

  /**
   * 账号是否过期
   */
  private boolean isAccountNonExpired;

  /**
   * 账号是否锁定
   */
  private boolean isAccountNonLocked;

  /**
   * 密码是否过期
   */
  private boolean isCredentialsNonExpired;

  /**
   * 政治面貌
   */
  @Length(max = 20, message = "长度不能超过{max}个字符")
  private String politicalOutlook;

  /**
   * 职务
   */
  @Length(max = 100, message = "长度不能超过{max}个字符")
  private String duty;

  /**
   * 民族
   */
  @Length(max = 20, message = "长度不能超过{max}个字符")
  private String nation;

  /**
   * 是否为领导
   */
  private Boolean flagLeader;

  // ==================== 其他属性 ====================

  /**
   * 所属单位名称
   */
  @TableField(exist = false)
  private String unitName;

  /**
   * 所属科室名称
   */
  @TableField(exist = false)
  private String departmentName;

  /**
   * 管理员所属角色
   */
  @TableField(exist = false)
  @JsonIgnore
  private List<SysRole> roleList = new ArrayList<>();

  /**
   * 管理员所拥有的所有权限
   */
  @TableField(exist = false)
  @JsonIgnore
  private List<SysPurview> purviewList = new ArrayList<>();

  /**
   * 管理员所拥有的所有 GrantedAuthority
   */
  @TableField(exist = false)
  @JsonIgnore
  private Collection<? extends GrantedAuthority> authorities = new ArrayList<>();

  /**
   * 管理员所拥有的 menu
   */
  @TableField(exist = false)
  @JsonIgnore
  private String menu;

  /**
   * 总登录次数
   */
  @TableField(exist = false)
  private Integer loginNumber;

}
